import { useMessage } from '@/hooks'
import { ref, unref, watch } from 'vue'
import { bwUtils } from '@bitwit/utils'
import { useComDesignStoreWithOut } from '@/store'

import type { BwCustomComStructModel } from '@bitwit/base-com-render'
import type { BwDomNodeInfo, BwNodeSlotInfo } from './model'

export function useDomTree() {
  const { createConfirm } = useMessage()
  const designStore = useComDesignStoreWithOut()

  const dataSource = ref<Array<BwDomNodeInfo>>([])

  /** 选中表单节点元素*/
  const onSelect = (nodeId: string) => {
    designStore.onSeleteNodeInfo(nodeId)
  }

  /** 移除表单节点元素 */
  const onNodeRmove = (nodeId: string) => {
    createConfirm({
      iconType: 'warning',
      title: () => '温馨提醒',
      content: () => `移除当前节，可能会影响到组件运行，是否确定移除？`,
      onOk: async () => {
        designStore.onRemoveNodeEle(nodeId)
      },
    })
  }
  /**
   * 表单节点元素临时隐藏（在设计画布上不展示）
   */
  const onNodeHide = (nodeId: string, isHide) => {
    designStore.onHideNodeEle(nodeId, isHide)
  }

  /** 当前自定义组件 DOM 节点树 */
  const getDomNodeTree = (
    structList: Array<BwCustomComStructModel>
  ): Array<BwDomNodeInfo> => {
    const treeData: Array<BwDomNodeInfo> = []
    const curHideNodeIds = designStore.curHideNodeIds

    if (Array.isArray(structList) && structList.length) {
      structList.forEach((n) => {
        const childs = n.children || {}
        const slotList = Object.keys(childs).map((slotName): BwNodeSlotInfo => {
          return {
            type: 'solt',
            slotKey: slotName,
            slotName: slotName,
            isExpand: true,
            isShowSlotBox: true,
            children: getDomNodeTree(childs[slotName] || []),
          }
        })

        treeData.push({
          type: 'node',
          comKey: n.comName,
          nodeId: n.nodeId,
          nodeName: n.nodeName,
          children: slotList,
          isSelect: false,
          isExpand: true,
          isHide: curHideNodeIds.includes(n.nodeId),
        })
      })
    }
    return treeData
  }

  watch(
    () => designStore.getStructList,
    (newVal) => {
      Array.isArray(newVal) && newVal.length
        ? (dataSource.value = getDomNodeTree(newVal))
        : (dataSource.value = [])
    },
    { deep: true, immediate: true }
  )

  watch(
    () => designStore.selectNodeEle,
    (newVal) => {
      const nodeId = newVal?.nodeId
      bwUtils.findTreeNode(
        unref(dataSource),
        (nodeInfo: BwDomNodeInfo | BwNodeSlotInfo) => {
          if (nodeInfo.type === 'node') {
            nodeInfo.isSelect = nodeId ? nodeId === nodeInfo.nodeId : false
          }
        }
      )
    },
    { deep: true, immediate: true }
  )

  watch(
    () => designStore.curHideNodeIds,
    (newVal) => {
      const nodeIds = newVal ?? []
      bwUtils.findTreeNode(
        unref(dataSource),
        (nodeInfo: BwDomNodeInfo | BwNodeSlotInfo) => {
          if (nodeInfo.type === 'node') {
            nodeInfo.isHide = nodeIds.includes(nodeInfo.nodeId)
          }
        }
      )
    },
    { deep: true, immediate: true }
  )

  return { dataSource, onSelect, onNodeRmove, onNodeHide }
}
